
#继承，继承父类的方法
class Animal(object):
    def run(self):
        print('Animal is running')


class Dog(Animal):
    pass


class Cat(Animal):
        pass
ani=Animal()
ani.run()

dog=Dog()
dog.run()

cat=Cat()
cat.run()

#当子类和父类都存在相同的run()方法时，我们说，子类的r
# un()覆盖了父类的run()，在代码运行的时候，总是会调用子类的run()。这
# 样，我们就获得了继承的另一个好处：多态。

class Horse(Animal):
    def run(self):
        print("Horse is running")

horse=Horse()
horse.run()

# 判断一个变量是否是某个类型可以用isinstance()判断：
print(isinstance(horse,Horse))#子类就是子类
print(isinstance(horse,Animal))#子类也是父类
#要理解多态的好处

#比如有个接口

def Animalrun(Animal):
    print("=====================")
    Animal.run()
    print("=====================")

Animalrun(horse)
Animalrun(cat)

'''
对于一个变量，我们只需要知道它是Animal类型，无需确切
地知道它的子类型，就可以放心地调用run()方法，而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上，
由运行时该对象的确切类型决定，这就是多态真正的威力：调用方只管调用，不管细节，而当我们新增一种Animal的子类时，只要
确保run()方法编写正确，不用管原来的代码是如何调用的。这就是著名的“开闭”原则：
对扩展开放：允许新增Animal子类；

对修改封闭：不需要修改依赖Animal类型的run_twice()等函数。
'''

class Tortoise(Animal):
    def run(self):
        print("Tortois is running slowly")


Animalrun(Tortoise())

# 对于静态语言（例如Java）来说，如果需要传入Animal类型，则传
# 入的对象必须是Animal类型或者它的子类，否则，将无法调用run()方法。
#
# 对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只
# 需要保证传入的对象有一个run()方法就可以了：

class Timer(object):
    def run(self):
        print('.. timer is  start...')

#python 只要像鸭子就可以当子类了
Animalrun(Timer())


